#ifndef MAPRENDERER_H_
#define MAPRENDERER_H_

#include <stdint.h>
#include <map>

#include "Graphics.h"
#include "Transformation.h"
#include "Map.h"

#include "Route.h"


namespace opennav {

struct street_label {
	bool placed;
	Point place;
	int32_t dx;
	int32_t dy;
	std::string street_name;
	int32_t len_sq;
};

typedef std::map<uint32_t, street_label> street_label_map;

class MapRenderer {
public:
	MapRenderer();
	~MapRenderer();

	int render(const MapSelection& selection, const Transformation& transformation, CanvasInterface& image);
	int render(const MapSelection& selection, const Transformation& transformation, CanvasInterface& image, const Route* route);

private:
	void place_street_label(MapLine* line, CanvasInterface& canvas, std::vector<Point>& points, street_label_map& labels);
	void draw_street_labels(CanvasInterface& canvas, street_label_map& labels);
	void draw_hw_layer(Color color, const int width, vector<vector<Point>*>& layer, CanvasInterface &image, bool del);
	void draw_route(const MapSelection& selection, const Transformation& transformation, CanvasInterface& image, const Route* route);

private:
	/*
	 * Map Features
	 */
	static void line_weir(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		canvas.set_line_width(5);
		Color line_color(0x000000);
		canvas.set_foreground_color(line_color);
		canvas.draw_lines(points);
	}

	static void line_stream(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		int width = 3 * 256 / level;
		if (width < 3) width = 3;
		if (width > 24) width = 24;
		canvas.set_line_width(width);
		Color line_color(0x6495ed);
		canvas.set_foreground_color(line_color);
		canvas.draw_lines(points);
	}

	static void line_river(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		int width = 10 * 256 / level;
		if (width < 10) width = 10;
		if (width > 80) width = 80;
		canvas.set_line_width(10);
		Color line_color(0x6495ed);
		canvas.set_foreground_color(line_color);
		canvas.draw_lines(points);
	}

	static void line_rail(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		canvas.set_line_width(2);
		Color line_color(0x3c3c3c);
		canvas.set_foreground_color(line_color);
		canvas.draw_lines(points);
	}

	static void line_monorail(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		line_rail(canvas, points, level);
	}

	static void line_funicular(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		line_rail(canvas, points, level);
	}

	static void line_tram(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		line_rail(canvas, points, level);
	}

	static void line_subway(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		canvas.set_line_width(2);
		Color line_color(0x5c5c5c);
		canvas.set_foreground_color(line_color);
		canvas.draw_lines(points);
	}

	static void line_raceway(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		int width = 4 * 256 / level;
		if (width < 4) width = 4;
		if (width > 32) width = 32;
		canvas.set_line_width(width);
		Color line_color(0x808080);
		canvas.set_foreground_color(line_color);
		canvas.draw_lines(points);
	}

	static void line_border_country(CanvasInterface& canvas, std::vector<Point>& points, int level) {
		canvas.set_line_width(1);
		Color line_color(0x000000);
		canvas.set_foreground_color(line_color);
		canvas.draw_lines(points);
	}

private:
	const static uint32_t COLOR_BACKGROUND = 0xf1eee8;

	const static uint32_t LINE_HWTYPE0_COLOR = 0x6b8e23;
	const static uint32_t LINE_HWTYPE1_COLOR = 0xffa500;
	const static uint32_t LINE_HWTYPE2_COLOR = 0xf5deb3;
	const static uint32_t LINE_HWTYPE3_COLOR = 0xfafad2;
	const static uint32_t LINE_HWTYPE4_COLOR = 0xfafad2;
	const static uint32_t LINE_HWTYPE5_COLOR = 0xfafad2;
	const static uint32_t LINE_HWTYPE6_COLOR = 0x666666;

	const static uint32_t LABEL_CITY_LARGE_COLOR = 0x000000;
	const static uint32_t LABEL_CITY_SMALL_COLOR = 0x000000;
};

}

#endif /* MAPRENDERER_H_ */
